﻿// Copyright (C) Jari Hautio <jari.hautio@iki.fi> 2008. Licensed under GPLv2. See LICENSE.txt in solution folder.
using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

/*
namespace RyijyApp
{
    /// <summary>
    /// A test class for trying out asynchroinous image processing using a wrapper class.
    /// For some things it seems to do the trick, but overall, a better solution is needed.
    /// Main problem was that while worker thread is processing, new request queue up, but 
    /// they cannot cancel other queued requests.
    /// Also update processing, which requires invoke processing, do not look 
    /// safe enough and syncronizing on when previous worker is ready is a pain.
    /// </summary>
    class AsyncImageProcessor
    {
        class MyImageProcessor : ImageProcessor
        {
            System.ComponentModel.BackgroundWorker worker= null;
            public System.Threading.ManualResetEvent readyEvent = new System.Threading.ManualResetEvent(true);
            
            public MyImageProcessor(System.ComponentModel.BackgroundWorker w)
            {
                worker = w;
                worker.DoWork += new System.ComponentModel.DoWorkEventHandler(worker_DoWork);
                worker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(worker_RunWorkerCompleted);
                worker.WorkerSupportsCancellation = true;
            }

            void worker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
            {
            }


            void worker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
            {
                readyEvent.Reset();
                base.UpdateTargetImage();
                if (worker.CancellationPending) 
                    e.Cancel = true;
                e.Result = TargetImage;
                readyEvent.Set();
            }
            public override void UpdateTargetImage()
            {
                System.Diagnostics.Debug.Assert(!worker.IsBusy);
                worker.RunWorkerAsync();
            }
            protected override bool  IsUpdateCancelled()
            {
                return worker.CancellationPending;
            }
        }
        MyImageProcessor ip = null;
        System.Windows.Forms.Control owner=null;
        System.ComponentModel.BackgroundWorker worker = new System.ComponentModel.BackgroundWorker();

        public AsyncImageProcessor(System.Windows.Forms.Control ownerControl)
        {
            ip = new MyImageProcessor(worker);
            targetDepth = ip.TargetDepth;
            removedColors = ip.RemovedColors;
            diversityFactor = ip.DiversityFactor;
            owner = ownerControl;
            worker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(worker_ProgressChanged);
            ip.ResetHandler += new EventHandler(ip_ResetHandler);
            ip.ColorsChanged += new EventHandler(ip_ColorsChanged);
        }

        void ip_ColorsChanged(object sender, EventArgs e)
        {
            UpdateFields();
            if (owner.InvokeRequired)
            {
                if (!worker.CancellationPending)
                    owner.Invoke(new EventHandler(ip_ColorsChanged), new object[] { e });
                return;
            }
            if (ColorsChanged != null)
                ColorsChanged(this, EventArgs.Empty);
        }

        void ip_ResetHandler(object sender, EventArgs e)
        {
            if (owner.InvokeRequired)
            {
                if (!worker.CancellationPending)
                    owner.Invoke(new EventHandler(ip_ResetHandler), new object[] { e });
                return;
            }
            if (ResetHandler != null)
                ResetHandler(this, e);
        }

        void worker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
        {
        }

        Dictionary<Color, int> targetHistogram = new Dictionary<Color, int>();
        public Dictionary<Color, int> TargetHistogram { get { return targetHistogram; } }

        public CustomPalette CustomColorPalette
        {
            get { return ip.CustomColorPalette; }
            set { ip.CustomColorPalette = value; }
        }

        public ColorPicker.DistanceMode ColorDistanceMode { get { return ip.ColorDistanceMode; } set { ip.ColorDistanceMode = value; } }

        /// <summary>
        /// Reset event is fires when Original Image changes.
        /// </summary>
        public event EventHandler ResetHandler;

        private int targetDepthColors=0;
        public int TargetDepthColors
        {
            get { return targetDepthColors; }
        }
        private Bitmap targetImage = null;

        /// <summary>
        /// Gets or sets final image.
        /// </summary>
        public Bitmap TargetImage
        {
            get { return targetImage; }
        }

        /// <summary>
        /// Gets or sets image size properties.
        /// </summary>
        public RyijyProp RyijyProperties
        {
            get { return ip.RyijyProperties; }
            set { ip.RyijyProperties= value; }
        }

        /// <summary>
        /// Gets number of colors in final image.
        /// </summary>
        public int TargetColors { get { return targetHistogram.Keys.Count; } }
        /// <summary>
        /// Gets number of colors in original image.
        /// </summary>
        public int OriginalColors { get { return ip.OriginalColors; } }

        int scaledColors = 0;
        /// <summary>
        /// Gets number of colors in resized image.
        /// </summary>
        public int ScaledColors { get { return scaledColors; } }

        void Sync()
        {
            
            if (worker.IsBusy)
            {
                if (!worker.CancellationPending)
                    worker.CancelAsync();
                ip.readyEvent.WaitOne();
                while (worker.IsBusy)
                    Application.DoEvents();

            }
        }
        /// <summary>
        /// Color depth conversion target
        /// </summary>
        private int targetDepth =0 ;

        /// <summary>
        /// Gets or sets color depth conversion target
        /// </summary>
        public int TargetDepth
        {
            get { return ip.TargetDepth; }
            set
            {
                Sync();
                ip.TargetDepth = value;
            }
        }
        /// <summary>
        /// Color reduction target
        /// </summary>
        private int removedColors = 0;
        /// <summary>
        /// Maximum for removed colors.
        /// </summary>
        public int MaxRemovedColors { get { return ip.MaxRemovedColors; } }
        /// <summary>
        /// Mininum for removed colors.
        /// </summary>
        public int MinRemovedColors { get { return ip.MinRemovedColors; } }

        /// <summary>
        /// Get or set color removal target.
        /// MinRemovedColors and MxRemovedColors define the interval.
        /// </summary>
        public int RemovedColors
        {
            get { return removedColors; }
            set { if (value != ip.RemovedColors) { Sync(); ip.RemovedColors = value; } }
        }
        private System.Drawing.Imaging.ColorMatrix colorMatrix = null;
        public System.Drawing.Imaging.ColorMatrix ColorMatrix
        {
            get { return colorMatrix; }
            set { Sync(); ip.ColorMatrix = value; }
        }

        /// <summary>
        /// Event for notifying that colors in the target image have been changed
        /// </summary>
        public event EventHandler ColorsChanged;

        private double diversityFactor = 0;

        public double DiversityFactor
        {
            get { return diversityFactor; }
            set { Sync(); ip.DiversityFactor = value; }
        }

        public void Reset()
        {
            Sync();
            ip.Reset();
        }
        void UpdateFields()
        {
            diversityFactor = ip.DiversityFactor;
            colorMatrix = ip.ColorMatrix;
            removedColors = ip.RemovedColors;
            targetDepth = ip.TargetDepth;
            scaledColors = ip.ScaledColors;
            targetImage = ip.TargetImage;
            targetHistogram = ip.TargetHistogram;
        }
        public Bitmap OriginalImage
        {
            get { return ip.OriginalImage; }
            set
            {
                Sync();
                ip.OriginalImage = value;
            }
        }
        public void ResizeImage(int w, int h)
        {
            Sync();
            ip.ResizeImage(w, h);
            UpdateFields();
        }

    }
}
*/